package com.levi.listener;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 模拟消费者消费失败的情况
 * 消费者消费消息过程中出现异常，如果不设置手动ack，会一直重试，进入死循环
 * 解决方案：try catch+死信队列+手动ack,把消费出现异常的消息放进死信队列，让一个专门消费者进行消费
 */
//@Component
public class AckConsumer {

    @RabbitListener(queues = {"ttl"})
    public void connsumerMsg(String msg,
                             Channel channel,
                             CorrelationData correlationData,
                             @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {

        try {
            //对消息进行消费
            System.out.println("消费者收到ttl的消息为: "+msg);

            int a = 1 / 0;
            //出现异常 没办法走到手动ack这行代码，所以在catch里面进行ack设置，不重发,让消息直接进入死信队列中取
            channel.basicAck(tag,false);

            /**
             * 第一个参数:消息的tag
             * 第二个参数:是否重发，不重发的话会把消息打入死信队列
             * 第三个参数:设置为true的话会导致死循环,要设置为false，设置为false的话不会重发
             */
        } catch (Exception e) {
            //出现异常，通知mq把这条消息移除，移除之后放入死信队列，做额外的处理
            channel.basicNack(tag,false,false);
        }
    }
}
